package com.simafei.flow.web.config;

import com.simafei.flow.core.common.Condition;
import com.simafei.flow.core.json.ConditionDeserializer;
import com.simafei.flow.core.json.ConditionSerializer;
import com.simafei.flow.core.json.LocalDateDeserializer;
import com.simafei.flow.core.json.LocalDateSerializer;
import com.simafei.flow.core.json.LocalDateTimeDeserializer;
import com.simafei.flow.core.json.LocalDateTimeSerializer;
import com.simafei.flow.web.domain.graph.GraphNode;
import com.simafei.flow.web.domain.graph.GraphNodeDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 不生效的原因一般是 MappingJackson2HttpMessageConverter 对象在程序启动时创建了多个
 * 基础包中配置了 MappingJackson2HttpMessageConverter，导致应用服务工程中配置的 ObjectMapper 无效

 * 如果自己继承WebMvcConfigurer配置configureMessageConverters来自定义Json的一些序列化方式
 * 这个必须把ByteArrayHttpMessageConverter添加到第0个，不然swagger的文档地址会出现错误，无法渲染，api-docs返回base64编码后的数据

 * converters.add(0, new ByteArrayHttpMessageConverter());
 * converters.removeIf(MappingJackson2HttpMessageConverter.class::isInstance);
 * converters.add(1, mappingJackson2HttpMessageConverter());
 *
 * @author fengpengju
 */
@Configuration
@Slf4j
public class JacksonConfiguration {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return jacksonObjectMapperBuilder -> {
            jacksonObjectMapperBuilder.serializerByType(Long.class, NumberSerializer.INSTANCE);
            jacksonObjectMapperBuilder.serializerByType(Long.TYPE, NumberSerializer.INSTANCE);
            jacksonObjectMapperBuilder.serializerByType(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE);
            jacksonObjectMapperBuilder.deserializerByType(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
            jacksonObjectMapperBuilder.serializerByType(LocalDate.class, LocalDateSerializer.INSTANCE);
            jacksonObjectMapperBuilder.deserializerByType(LocalDate.class, LocalDateDeserializer.INSTANCE);
            jacksonObjectMapperBuilder.serializerByType(Condition.class, ConditionSerializer.INSTANCE);
            jacksonObjectMapperBuilder.deserializerByType(Condition.class, ConditionDeserializer.INSTANCE);
            jacksonObjectMapperBuilder.deserializerByType(GraphNode.class, GraphNodeDeserializer.INSTANCE);
        };
    }

}
